﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D; //网格画刷和渐变画刷在该命名空间定义
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _1025GDI
{
    enum BrushFlag { 实心画刷, 网格画刷, 两色线性渐变, 多色线性渐变, 中间向两侧均匀线性渐变, 钟形线性渐变, 两色径向渐变, 多色径向渐变, 位图画刷 };

    public partial class Form1 : Form
    {
        //以下若干个类全局变量，保存用户因在菜单上操作而创建的绘图工具
        //形状标志：0---清屏，1---直线，2---矩形，3---圆形，4---多边形，
        //5---1条贝塞尔曲线，6---2条连续贝塞尔，7---折线，8 ---文字, 
        //9---显示图像（原始大小）, 10---显示图像（缩放）,11---显示图像（缩放+变形）
        //12---在图像对象上绘图后再显示，13---截屏
        int flag = 0;
        //画刷对象的引用
        Brush currentBrush = new SolidBrush(Color.Red);
        BrushFlag currentBrushflag = BrushFlag.实心画刷;
        //颜色变量
        Color currentColor = Color.Red;
        //画笔宽度
        int penWidth = 1;
        //绘制图形的矩形区域
        Rectangle rect1 = new Rectangle(20, 40, 200, 150);
        Rectangle rect2 = new Rectangle(250, 40, 200, 150);
        //图形路径，其中可存放多个图形信息。用于径向渐变
        GraphicsPath gp;
        //截屏功能所需的图片对象
        Bitmap bmpPrintScreen;
        public Form1()
        {
            InitializeComponent();
            //以下代码为截屏功能做准备
            //得到屏幕的宽度和高度（像素为单位）
            int iScreenWidth = Screen.PrimaryScreen.Bounds.Width;
            int iScreenHeight = Screen.PrimaryScreen.Bounds.Height;
            //创建与屏幕大小相同的、只有内存空间但没有内容的位图对象
            bmpPrintScreen = new Bitmap(iScreenWidth, iScreenHeight);
        }

        private void 形状ToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            foreach (ToolStripMenuItem tsmi in 形状ToolStripMenuItem.DropDownItems)
            {
                tsmi.Checked = false;
            }
            if (flag == 1) 直线ToolStripMenuItem.Checked = true;
            if (flag == 2) 矩形ToolStripMenuItem.Checked = true;
            if (flag == 3) 圆形ToolStripMenuItem.Checked = true;
            if (flag == 4) 多边形ToolStripMenuItem.Checked = true;
            if (flag == 5) 一条贝塞尔曲线ToolStripMenuItem.Checked = true;
            if (flag == 6) 两条贝塞尔曲线ToolStripMenuItem.Checked = true;
            if (flag == 7) 折线ToolStripMenuItem.Checked = true;
            if (flag == 8) 显示文字ToolStripMenuItem.Checked = true;
            if (flag == 9) 显示图像原始大小ToolStripMenuItem.Checked = true;
            if (flag == 10) 显示图像缩放ToolStripMenuItem.Checked = true;
            if (flag == 11) 显示图像缩放变形ToolStripMenuItem.Checked = true;
            if (flag == 12) 在图像上绘制后再显示ToolStripMenuItem.Checked = true;
            if (flag == 13) 截屏ToolStripMenuItem.Checked = true;
            if (flag == 0) 清屏ToolStripMenuItem.Checked = true;
        }

        private void 显示图像缩放变形ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 11;
            this.Invalidate();
        }

        private void 清屏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 0;
            this.Invalidate();//强制刷新整个窗口
        }

        private void 直线ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 1;
            this.Invalidate();
        }

        private void 矩形ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 2;
            this.Invalidate();
        }

        private void 圆形ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 3;
            this.Invalidate();
        }

        private void 多边形ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 4;
            this.Invalidate();
        }

        private void 一条贝塞尔曲线ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 5;
            this.Invalidate();
        }

        private void 两条贝塞尔曲线ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 6;
            this.Invalidate();
        }

        private void 折线ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 7;
            this.Invalidate();
        }

        private void 显示文字ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 8;
            this.Invalidate();
        }

        private void 显示图像原始大小ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 9;
            this.Invalidate();
        }

        private void 显示图像缩放ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 10;
            this.Invalidate();
        }

        private void 在图像上绘制后再显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 12;
            this.Invalidate();
        }

        private void 截屏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            flag = 13;
            this.Invalidate();
        }

        private void 画刷ToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            foreach (ToolStripMenuItem tsmi in 画刷ToolStripMenuItem.DropDownItems)
            {
                tsmi.Checked = false;
            }
            if (currentBrushflag == BrushFlag.实心画刷)
                实心画刷ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.网格画刷)
                网格画刷ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.两色线性渐变)
                两色渐变画刷ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.多色线性渐变)
                多色渐变画刷ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.中间向两侧均匀线性渐变)
                中间向两侧均匀渐变ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.钟形线性渐变)
                中间向两侧钟形渐变ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.两色径向渐变)
                两色径向渐变ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.多色径向渐变)
                多色径向渐变ToolStripMenuItem.Checked = true;
            if (currentBrushflag == BrushFlag.位图画刷)
                位图画刷ToolStripMenuItem.Checked = true;
        }

        private void 实心画刷ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentBrush = new SolidBrush(currentColor);
            currentBrushflag = BrushFlag.实心画刷;
            Invalidate();
        }

        private void 网格画刷ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentBrush = new HatchBrush(
                HatchStyle.Cross, currentColor, Color.LightGray);
            currentBrushflag = BrushFlag.网格画刷;
            Invalidate();
        }

        private void 两色渐变画刷ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentBrush = new LinearGradientBrush(
                rect2, currentColor, Color.White, LinearGradientMode.Horizontal);
            currentBrushflag = BrushFlag.两色线性渐变;
            Invalidate();
        }

        private void 多色渐变画刷ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentBrush = new LinearGradientBrush(
                rect2, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
            currentBrushflag = BrushFlag.多色线性渐变;
            Color[] colors = new Color[4];
            colors[0] = Color.Red;
            colors[1] = Color.Green;
            colors[2] = Color.Blue;
            colors[3] = Color.Yellow;
            ColorBlend cb = new ColorBlend();//Blend---混合、调和的意思
            cb.Positions = new float[4] { 0.0F, 0.33F, 0.66F, 1.0F };//各颜色分界位置
            cb.Colors = colors;
            ((LinearGradientBrush)currentBrush).InterpolationColors = cb;
            Invalidate();
        }

        private void 中间向两侧均匀渐变ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentBrush = new LinearGradientBrush(
                rect2, currentColor, Color.White, LinearGradientMode.Vertical);
            //中间向两边过渡效果
            ((LinearGradientBrush)currentBrush).SetBlendTriangularShape(0.5F);
            currentBrushflag = BrushFlag.中间向两侧均匀线性渐变;
            Invalidate();
        }

        private void 中间向两侧钟形渐变ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentBrush = new LinearGradientBrush(
                rect2, currentColor, Color.White, LinearGradientMode.Vertical);
            //钟型曲线过渡效果
            ((LinearGradientBrush)currentBrush).SetSigmaBellShape(0.8F);
            currentBrushflag = BrushFlag.钟形线性渐变;
            Invalidate();
        }

        private void 两色径向渐变ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (flag < 2 || flag > 4) return;
            gp = new GraphicsPath();//径向渐变画刷所需图形路径
            if (flag == 2) gp.AddRectangle(rect2);
            if (flag == 3) gp.AddEllipse(rect2);
            if (flag == 4)
            {
                Point[] poly2 = new Point[3];
                poly2[0] = rect2.Location;
                poly2[1] = rect2.Location + new Size(rect2.Width, 0);
                poly2[2] = rect2.Location + new Size(rect2.Width / 2, rect2.Height);
                gp.AddLines(poly2);
                gp.CloseFigure();
            }
            currentBrush = new PathGradientBrush(gp);
            ((PathGradientBrush)currentBrush).CenterColor = Color.White;
            ((PathGradientBrush)currentBrush).SurroundColors = new Color[] { currentColor };
            ((PathGradientBrush)currentBrush).CenterPoint = new Point(
                rect2.X + rect2.Width / 2, rect2.Y + rect2.Height / 2);
            currentBrushflag = BrushFlag.两色径向渐变;
            Invalidate();
        }

        private void 多色径向渐变ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (flag < 2 || flag > 4) return;
            gp = new GraphicsPath();
            if (flag == 2) gp.AddRectangle(rect2);
            if (flag == 3) gp.AddEllipse(rect2);
            if (flag == 4)
            {
                Point[] poly2 = new Point[3];
                poly2[0] = rect2.Location;
                poly2[1] = rect2.Location + new Size(rect2.Width, 0);
                poly2[2] = rect2.Location + new Size(rect2.Width / 2, rect2.Height);
                gp.AddLines(poly2);
                gp.CloseFigure();
            }
            currentBrush = new PathGradientBrush(gp);
            ((PathGradientBrush)currentBrush).CenterColor = Color.White;
            ((PathGradientBrush)currentBrush).SurroundColors =
                new Color[] { Color.Red, Color.Green, Color.Blue };
            ((PathGradientBrush)currentBrush).CenterPoint =
                new Point(rect2.X + rect2.Width / 2, rect2.Y + rect2.Height / 2);
            currentBrushflag = BrushFlag.多色径向渐变;
            Invalidate();
        }

        private void 位图画刷ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Bitmap bt = new Bitmap("大理石.png");
            currentBrush = new TextureBrush(bt);
            currentBrushflag = BrushFlag.位图画刷;
            Invalidate();
        }

        private void 颜色ToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            foreach (ToolStripMenuItem tsmi in 颜色ToolStripMenuItem.DropDownItems)
            {
                tsmi.Checked = false;
            }
            if (currentColor == Color.Red) 红色ToolStripMenuItem.Checked = true;
            if (currentColor == Color.Green) 绿色ToolStripMenuItem.Checked = true;
            if (currentColor == Color.Blue) 蓝色ToolStripMenuItem.Checked = true;
        }

        private void 红色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentColor = Color.Red;
            Invalidate();
        }

        private void 绿色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentColor = Color.Green;
            Invalidate();
        }

        private void 蓝色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentColor = Color.Blue;
            Invalidate();
        }

        private void 画笔宽度ToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            foreach (ToolStripMenuItem tsmi in 画笔宽度ToolStripMenuItem.DropDownItems)
            {
                tsmi.Checked = false;
            }
            //注意VS自动生成的菜单项的名称
            //由于菜单项文本以数字开头，而对象名不能以数字开头
            if (penWidth == 1) 像素ToolStripMenuItem.Checked = true;
            if (penWidth == 5) 像素ToolStripMenuItem1.Checked = true;
            if (penWidth == 10) 像素ToolStripMenuItem2.Checked = true;
            if (penWidth == 20) 像素ToolStripMenuItem3.Checked = true;
        }

        private void 像素ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            penWidth = 1;
            this.Invalidate();
        }

        private void 像素ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            penWidth = 5;
            this.Invalidate();
        }

        private void 像素ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            penWidth = 10;
            this.Invalidate();
        }

        private void 像素ToolStripMenuItem3_Click(object sender, EventArgs e)
        {
            penWidth = 20;
            this.Invalidate();
        }

        

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            switch (flag)
            {
                case 0: g.Clear(Color.White); break; //清屏
                case 1: //直线
                    //使用颜色创建画笔
                    g.DrawLine(new Pen(currentColor, penWidth),
new Point(40, 40), new Point(200, 200));
                    //使用画刷创建画笔
                    g.DrawLine(new Pen(currentBrush, penWidth),
new Point(rect2.X, rect2.Y),
new Point(rect2.X + rect2.Width, rect2.Y + rect2.Height));
                    break;
                case 2://矩形
                    //空心矩形
                    g.DrawRectangle(new Pen(currentColor, penWidth), rect1);
                    //填充矩形
                    g.FillRectangle(currentBrush, rect2);
                    break;
                case 3:
                    //空心椭圆
                    g.DrawEllipse(new Pen(currentColor, penWidth), rect1);
                    //填充椭圆
                    g.FillEllipse(currentBrush, rect2);
                    break;
                case 4:
                    //空心多边形
                    Point[] poly1 = new Point[3];
                    poly1[0] = rect1.Location;
                    poly1[1] = rect1.Location + new Size(rect1.Width, 0);
                    poly1[2] = rect1.Location + new Size(rect1.Width / 2, rect1.Height);
                    g.DrawPolygon(new Pen(currentColor, penWidth), poly1);
                    //填充多边形
                    Point[] poly2 = new Point[3];
                    poly2[0] = rect2.Location;
                    poly2[1] = rect2.Location + new Size(rect2.Width, 0);
                    poly2[2] = rect2.Location + new Size(rect2.Width / 2, rect2.Height);
                    g.FillPolygon(currentBrush, poly2);
                    break;
                case 5:     //一条贝塞尔曲线
                    Point pt1 = new Point(40, 150);  //起始点
                    Point pt2 = new Point(140, 60);  //控制点
                    Point pt3 = new Point(240, 280); //控制点
                    Point pt4 = new Point(440, 100); //终止点
                    g.DrawBezier(new Pen(currentColor, penWidth), pt1, pt2, pt3, pt4);
                    //绘制控制点
                    g.FillRectangle(new SolidBrush(Color.Black), pt1.X - 5, pt1.Y - 5, 10, 10);
                    g.FillRectangle(new SolidBrush(Color.Black), pt2.X - 5, pt2.Y - 5, 10, 10);
                    g.FillRectangle(new SolidBrush(Color.Black), pt3.X - 5, pt3.Y - 5, 10, 10);
                    g.FillRectangle(new SolidBrush(Color.Black), pt4.X - 5, pt4.Y - 5, 10, 10);
                    break;
                case 6:     //两条连续贝塞尔曲线
                    Point[] bezierPoints = new Point[7];
                    bezierPoints[0] = new Point(40, 150);    //起始点
                    bezierPoints[1] = new Point(140, 60);   //控制点
                    bezierPoints[2] = new Point(240, 280);  //控制点
                    bezierPoints[3] = new Point(340, 100);  //中间点
                    bezierPoints[4] = new Point(440, 60);   //控制点
                    bezierPoints[5] = new Point(540, 280);  //控制点
                    bezierPoints[6] = new Point(640, 100);  //终止点
                    g.DrawBeziers(new Pen(currentColor, penWidth), bezierPoints);
                    //绘制控制点
                    foreach (Point pt in bezierPoints)
                    {
                        g.FillRectangle(new SolidBrush(Color.Black), pt.X - 5, pt.Y - 5, 10, 10);
                    }
                    break;
                case 7:     //折线
                    Point[] lines = new Point[4];
                    lines[0] = rect1.Location;
                    lines[1] = rect1.Location + new Size(rect1.Width, rect1.Height);
                    lines[2] = rect2.Location;
                    lines[3] = rect2.Location + new Size(rect2.Width, rect2.Height);
                    g.DrawLines(new Pen(currentColor, penWidth), lines);
                    break;
                case 8: //文字
                    Font font = new Font("黑体", 80);
                    g.DrawString("我爱你，中国！", font, currentBrush, new Point(20, 50));
                    break;
                case 9:     //显示图像（原始大小）
                    Bitmap bt = new Bitmap("cn-wp2.jpg");
                    g.DrawImage(bt, 0, 40);
                    break;
                case 10:    //显示图像（缩放）
                    Bitmap bt1 = new Bitmap("cn-wp2.jpg");
                    //将图像显示在指定区域内
                    g.DrawImage(bt1, new Rectangle(0, 40, 500, 400));
                    break;
                case 11:    //显示图像（缩放+变形）
                    Bitmap bt2 = new Bitmap("cn-wp2.jpg");
                    //三个点决定一个平行四边形
                    //图像将扭曲适应该平行四边形
                    Point[] pts = new Point[3];
                    pts[0] = new Point(100, 40);
                    pts[1] = new Point(600, 40);
                    pts[2] = new Point(200, 400);
                    g.DrawImage(bt2, pts);
                    break;
                case 12:        //在图像对象上绘图后再显示
                    Bitmap bt3 = new Bitmap("cn-wp2.jpg");
                    Graphics bg = Graphics.FromImage(bt3); //从图片上获取绘图对象
                    bg.SmoothingMode = SmoothingMode.HighQuality;   //抗锯齿
                    Rectangle trc = new Rectangle(10, 10, 300, 120);//显示文字的区域
                    GraphicsPath tgp = new GraphicsPath(); //径向渐变画刷所需图形路径
                    tgp.AddEllipse(trc);
                    PathGradientBrush br = new PathGradientBrush(tgp);
                    br.CenterColor = Color.White;
                    br.SurroundColors = new Color[] { Color.Transparent };
                    br.CenterPoint = new Point(trc.X + trc.Width / 2, trc.Y + trc.Height / 2);
                    bg.FillEllipse(br, trc);
                    StringFormat format = new StringFormat();
                    format.Alignment = StringAlignment.Center;   //水平居中
                    format.LineAlignment = StringAlignment.Center;  //垂直居中
                    //绘制在一个矩形区域内
                    bg.DrawString("万里长城", new Font("黑体", 30),
new SolidBrush(Color.Blue),
trc,
format);
                    g.DrawImage(bt3, 0, 40);
                    break;
                case 13://截屏
                    Graphics bmpg = Graphics.FromImage(bmpPrintScreen);
                    bmpg.CopyFromScreen(0, 0, 0, 0,
new Size(bmpPrintScreen.Width, bmpPrintScreen.Height));
                    //g.DrawImage(bmpPrintScreen, new Rectangle(new Point(0, 0), ClientSize));
                    //由于窗体的客户区包括菜单所在区域，截屏保存的图片在显示时，会被菜单盖住，
                    //所以计算实际的显示区域大小
                    Rectangle actualClientRect = new Rectangle(
                        ClientRectangle.X,
                        ClientRectangle.Y + menuStrip1.Height,
                        ClientRectangle.Width,
                        ClientRectangle.Height - menuStrip1.Height);
                    g.DrawImage(bmpPrintScreen, actualClientRect);
                    break;
            }
        }
    }
}
   

